package crm.base.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import crm.system.entity.Authority;
import crm.system.entity.Resource;
import crm.system.mapper.ResourceMapper;

/**
 * 自定义"资源-权限"源数据类
 * 
 * @see org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource
 * 
 * @author Zhang Qiongbiao
 * 
 */
public class MyFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

	@Autowired
	private ResourceMapper resourceMapper;

	private Map<String, Collection<ConfigAttribute>> resourcesMap = new HashMap<String, Collection<ConfigAttribute>>();
	private PathMatcher pathMatcher = new AntPathMatcher();
	
	public void init() {
		obtainResourcesMap();
	}

	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		// HttpServletRequest request = ((FilterInvocation) object).getRequest();
		String url = ((FilterInvocation) object).getRequestUrl();

		int firstQuestionMarkIndex = url.indexOf("?");
		if (firstQuestionMarkIndex != -1) {
			url = url.substring(0, firstQuestionMarkIndex);
		}
		
		for (Entry<String, Collection<ConfigAttribute>> entry : resourcesMap.entrySet()) {
			if (pathMatcher.match(url, entry.getKey())) {
				return entry.getValue();
			}
		}
		
		return null;
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
//		Set<ConfigAttribute> allAttributes = new HashSet<ConfigAttribute>();

//		for (Entry<String, Collection<ConfigAttribute>> entry : resourcesMap.entrySet()) {
//			allAttributes.addAll(entry.getValue());
//		}
		return null;
	}

	@Override
	public boolean supports(Class<?> clazz) {
		return FilterInvocation.class.isAssignableFrom(clazz);
	}

	private void obtainResourcesMap() {
		List<Resource> resources = resourceMapper.getAllResourceAuthorities();

		Collection<ConfigAttribute> configAttributes = null;
		for (Resource resource : resources) {
			configAttributes = new ArrayList<ConfigAttribute>();
			for (Authority authority : resource.getAuthorities()) {
				configAttributes.add(new SecurityConfig(authority.getName()));
			}
			resourcesMap.put(resource.getValue(), configAttributes);
		}
	}

}
